﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

namespace Vision.Utilities.CMS6UpdateTool
{
    [ConfigurationElementType(typeof(AutoUpdateSiteFileProcessorConfigurationElement))]
    public class SiteFileUpdateProcessor : IUpdateProcessor
    {
        #region Ctor
        public SiteFileUpdateProcessor(IEnumerable<SiteFileOperator> operators, string packageFolder, int order = 0)
        {
            Operators = operators;
            Order = order;
            PackageFolder = packageFolder;
        }
        #endregion

        #region Properties
        public int Order { get; private set; }
        public string PackageFolder { get; private set; }
        public IEnumerable<SiteFileOperator> Operators { get; private set; }
        #endregion

        #region Process
        public void Process(UpdateProcessorContext context)
        {
            var releaseBaseFolder = FileSystemUtility.Combine(context.ExtractedPackagePath, PackageFolder);
            var siteBaseFolder = context.ItemUpdateContext.Args.SiteFolderPath;
            
            foreach(var op in Operators.OrderBy(c=>c.Order).ToList())
            {
                DoOperate(op, context, releaseBaseFolder, siteBaseFolder);
            }
        }
        #endregion
        
        #region Helper Methods
        protected void DoOperate(SiteFileOperator op, UpdateProcessorContext context, string releaseBaseFolder, string siteBaseFolder)
        {
            var releaseSiteFolder = FileSystemUtility.Combine(releaseBaseFolder, op.Folder);
            var originSiteFolder = FileSystemUtility.Combine(siteBaseFolder, op.Folder);

            var operatorFolder = op.Target ? originSiteFolder : releaseSiteFolder;
            var excludedFiles = string.IsNullOrEmpty(op.ExcludedFiles) ? new string[0] : op.ExcludedFiles.Split(',').ToArray();
            excludedFiles = excludedFiles.Select(c => FileSystemUtility.Combine(operatorFolder, c)).ToArray();
            switch (op.Action)
            {
                case SiteFileOperateAction.Delete:
                    FileSystemUtility.DeleteFolder(operatorFolder, true, excludedFiles);
                    break;
                case SiteFileOperateAction.Copy:
                    FileSystemUtility.CopyFolder(releaseSiteFolder, originSiteFolder, true);
                    break;
                case SiteFileOperateAction.Clear:
                    FileSystemUtility.ClearSubFolders(operatorFolder, true, excludedFiles);
                    break;
                case SiteFileOperateAction.None:
                default: break;
            }
        }
        #endregion
    }
}